package com.sp.scmdb.serviceImpl;

import java.util.List;
import java.util.Map;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import com.google.common.collect.Lists;
import com.sp.scmdb.bean.LabelIOBean;
import com.sp.scmdb.bean.RealTimeLabelIOBeanBean;
import com.sp.scmdb.bean.UserBean;
import com.sp.scmdb.dao.EmployeeDao;
import com.sp.scmdb.dao.His_LabelIODao;
import com.sp.scmdb.dao.LabelIODao;
import com.sp.scmdb.dao.LabelReadingMachineDao;
import com.sp.scmdb.dao.PathDao;
import com.sp.scmdb.dao.ViewRealEmpDataDao;
import com.sp.scmdb.entity.Employee;
import com.sp.scmdb.entity.His_LabelIO;
import com.sp.scmdb.entity.LabelIO;
import com.sp.scmdb.entity.LabelReadingMachine;
import com.sp.scmdb.entity.Path;
import com.sp.scmdb.entity.SuperLabelIO;
import com.sp.scmdb.service.LabelIOService;
import com.sp.scmdb.utils.GroupList;

@Service("labelIOService")
public class LabelIOServiceImpl implements LabelIOService {

	private LabelIODao labelIODao;
	private His_LabelIODao his_LabelIODao;
	private PathDao pathDao;
	private LabelReadingMachineDao labelReadingMachineDao;
	private EmployeeDao employeeDao;
	private ViewRealEmpDataDao viewRealEmpDataDao;

	public void setViewRealEmpDataDao(ViewRealEmpDataDao viewRealEmpDataDao) {
		this.viewRealEmpDataDao = viewRealEmpDataDao;
	}

	@Required
	public void setEmployeeDao(EmployeeDao employeeDao) {
		this.employeeDao = employeeDao;
	}

	@Required
	public void setHis_LabelIODao(His_LabelIODao his_LabelIODao) {
		this.his_LabelIODao = his_LabelIODao;
	}

	@Required
	public void setLabelReadingMachineDao(LabelReadingMachineDao labelReadingMachineDao) {
		this.labelReadingMachineDao = labelReadingMachineDao;
	}

	@Required
	public void setPathDao(PathDao pathDao) {
		this.pathDao = pathDao;
	}

	@Required
	public void setLabelIODao(LabelIODao labelIODao) {
		this.labelIODao = labelIODao;
	}

	@SuppressWarnings("unchecked")
	@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED)
	public LabelIOBean queryLabelIOAll(LabelIOBean entity, LabelIOBean oldLabelIOBean, UserBean user) {
		List<His_LabelIO> listLabelIO = Lists.newArrayList();
		List<LabelIOBean> lists = Lists.newArrayList();
		if (entity.equals(oldLabelIOBean)) {
			lists = oldLabelIOBean.getAllList();
		} else {
			List<Employee> employeeList = null;
			//StringBuffer empHql = new StringBuffer("from Employee where 1=1 ");
			StringBuffer empHql = new StringBuffer("select new Employee(e.id, e.empName, e.empLableID, e.empWorkID, " +
					"e.empSex, e.depart, e.workType, e.title, e.duty, e.workTime, e.shifts,e.bumen, " +
					"e.maxWorkTime) " +
					"from Employee as e " +
					" left join e.depart depart " +
					" left join e.workType workType" +
					" left join e.duty duty " +
					" left join e.workTime workTime " +
					" left join e.shifts shifts" +
					" left join e.title title " +
					" left join e.maxWorkTime maxWorkTime " +
					" left join e.bumen bumen " +
					"where 1=1 ");

			employeeList = employeeDao.queryHql(empHql.toString());
			Map<Integer, Employee> mapEmployee = GroupList.groupEmployee(employeeList);
			StringBuilder hql = new StringBuilder("select his.empID from His_LabelIO his where 1=1 ");
			if (StringUtils.isNotEmpty(entity.getDepID()) && !entity.getDepID().equals("0")) {
				hql.append(" and his.employee.empDepID = '" + entity.getDepID() + "'");
			}else if("0".equals(entity.getDepID())) {
				hql.append(" and his.employee.empDepID in (" + user.getRole().getDepartment() + ")");
			}
			if (StringUtils.isNotEmpty(entity.getDutyID()) && !entity.getDutyID().equals("0")) {
				hql.append(" and his.employee.empDutyID='" + entity.getDutyID() + "'");
			}
			if (StringUtils.isNotEmpty(entity.getWorkTypeID()) && !entity.getWorkTypeID().equals("0")) {
				hql.append(" and his.employee.empWorkTypeID='" + entity.getWorkTypeID() + "'");
			}
			if (StringUtils.isNotEmpty(entity.getEmpName().trim())) {
				hql.append(" and his.employee.empName like '%" + entity.getEmpName() + "%'");
			}
			if (StringUtils.isNotEmpty(entity.getLabelID().trim())) {
				hql.append(" and his.labelID ='" + entity.getLabelID() + "'");
			}
			if (StringUtils.isNotEmpty(entity.getInTime())) {
				hql.append(" and his.inTime >='" + entity.getInTime() + "'");
			}
			if (StringUtils.isNotEmpty(entity.getOutTime())) {
				hql.append(" and his.inTime<='" + entity.getOutTime() + "'");
			}
			hql.append(" group by his.empID");
			List<Integer> listEmpID = his_LabelIODao.findByHql(hql.toString());
			for (Integer empID : listEmpID) {
				Employee employee = mapEmployee.get(empID);
				His_LabelIO hisLabelIO = null;
				if (employee != null) {
					hisLabelIO = new His_LabelIO();
					hisLabelIO.setEmpID(empID);
					hisLabelIO.setEmployee(employee);
					listLabelIO.add(hisLabelIO);
				}
			}
			for (His_LabelIO labelIO : listLabelIO) {
				LabelIOBean labelIOBean = new LabelIOBean();
				labelIOBean.setEmpID(String.valueOf(labelIO.getEmpID()));
				labelIOBean.setLabelID(labelIO.getEmployee().getEmpLableID());
				labelIOBean.setEmpName(labelIO.getEmployee().getEmpName());
				labelIOBean.setDepID(labelIO.getEmployee().getDepart().getDeptName());
				if (labelIO.getEmployee().getDuty() != null) {
					labelIOBean.setDutyID(labelIO.getEmployee().getDuty().getName());
				}
				if (labelIO.getEmployee().getWorkType() != null) {
					labelIOBean.setWorkTypeID(labelIO.getEmployee().getWorkType().getName());
				}
				if (!lists.contains(labelIOBean)) {
					lists.add(labelIOBean);
				}
			}
		}
		if (CollectionUtils.isNotEmpty(lists)) {
			entity.setAllList(lists);
			entity.setList(lists.subList(entity.getCurrentRow(), entity.getLastRow()));
		}
		return entity;
	}

	@SuppressWarnings("unchecked")
	@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED)
	public LabelIOBean queryHisLabelIODetail(LabelIOBean entity, LabelIOBean oldLabelIOBean) {
		List<His_LabelIO> lists = Lists.newArrayList();
		List<LabelReadingMachine> labelReadMachine = labelReadingMachineDao.queryAll();
		Map<String, LabelReadingMachine> mapReaders = GroupList.groupReaders(labelReadMachine);
		if (entity.equals(oldLabelIOBean)) {
			lists = oldLabelIOBean.getAllList();
			entity.setPageNo(entity.getPageNo());
		} else {
			StringBuilder hql = new StringBuilder("from His_LabelIO label where 1=1");
			if (StringUtils.isNotEmpty(entity.getEmpID())) {
				hql.append(" and empID='" + entity.getEmpID() + "'");
			}
			if (StringUtils.isNotEmpty(entity.getInTime())) {
				hql.append(" and inTime >='" + entity.getInTime() + "'");
			}
			if (StringUtils.isNotEmpty(entity.getOutTime())) {
				hql.append(" and inTime<='" + entity.getOutTime() + "'");
			}
			hql.append(" order by inTime");
			List<His_LabelIO> tempLists = his_LabelIODao.findByHql(hql.toString());
			if (MapUtils.isNotEmpty(mapReaders)) {
				for (His_LabelIO labelIO : tempLists) {
					String lrmID = String.valueOf(labelIO.getLrmID());
					if (mapReaders.get(lrmID) != null) {
						labelIO.setRmk(mapReaders.get(lrmID).getLrmName());
						lists.add(labelIO);
					}
				}
			}
			entity.setPageNo(1);
		}
		if (CollectionUtils.isNotEmpty(lists)) {
			His_LabelIO labelIO = lists.get(0);
			entity.setDepID(labelIO.getEmployee().getDepart().getDeptName());
			if (labelIO.getEmployee().getDuty() != null) {
				entity.setDutyID(labelIO.getEmployee().getDuty().getName());
			} else {
				entity.setDutyID("");
			}
			if (labelIO.getEmployee().getWorkType() != null) {
				entity.setWorkTypeID(labelIO.getEmployee().getWorkType().getName());
			} else {
				entity.setWorkTypeID("");
			}
			entity.setEmpName(labelIO.getEmployee().getEmpName());
			entity.setLabelID(String.valueOf(labelIO.getLabelID()));
			entity.setAllList(lists);
			entity.setPageSize(50);
			entity.setList(lists.subList(entity.getCurrentRow(), entity.getLastRow()));
		}
		return entity;
	}

	@SuppressWarnings("unchecked")
	@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED)
	public LabelIOBean queryLabelIODetail(LabelIOBean entity, LabelIOBean oldLabelIOBean) {
		List<LabelIO> lists = Lists.newArrayList();
		List<LabelReadingMachine> labelReadMachine = labelReadingMachineDao.queryAll();
		Map<String, LabelReadingMachine> mapReaders = GroupList.groupReaders(labelReadMachine);
		if (entity.equals(oldLabelIOBean)) {
			lists = oldLabelIOBean.getAllList();
		} else {
			StringBuilder hql = new StringBuilder("from LabelIO label where 1=1");
			if (StringUtils.isNotEmpty(entity.getEmpID())) {
				hql.append(" and empID='" + entity.getEmpID() + "'");
			}
			if (StringUtils.isNotEmpty(entity.getInTime())) {
				hql.append(" and inTime >='" + entity.getInTime() + "'");
			}else{
				entity.setInTime(new DateTime().toString("yyyy-MM-dd"));
			}
			if (StringUtils.isNotEmpty(entity.getOutTime())) {
				hql.append(" and inTime<='" + entity.getOutTime() + "'");
			}
			hql.append(" order by inTime");
			List<LabelIO> tempLists = labelIODao.findByHql(hql.toString());
			if (MapUtils.isNotEmpty(mapReaders)) {
				for (LabelIO labelIO : tempLists) {
					String lrmID = String.valueOf(labelIO.getLrmID());
					if (mapReaders.get(lrmID) != null) {
						labelIO.setRmk(mapReaders.get(lrmID).getLrmName());
						lists.add(labelIO);
					}
				}
			}
		}
		if (CollectionUtils.isNotEmpty(lists)) {
			LabelIO labelIO = lists.get(0);
			entity.setDepID(labelIO.getEmployee().getDepart().getDeptName());
			if (labelIO.getEmployee().getDuty() != null) {
				entity.setDutyID(labelIO.getEmployee().getDuty().getName());
			} else {
				entity.setDutyID("");
			}
			if (labelIO.getEmployee().getWorkType() != null) {
				entity.setWorkTypeID(labelIO.getEmployee().getWorkType().getName());
			} else {
				entity.setWorkTypeID("");
			}
			entity.setEmpName(labelIO.getEmployee().getEmpName());
			entity.setLabelID(String.valueOf(labelIO.getLabelID()));
			entity.setAllList(lists);
			entity.setPageSize(50);
			entity.setList(lists.subList(entity.getCurrentRow(), entity.getLastRow()));
		}
		return entity;
	}

	@SuppressWarnings("unchecked")
	@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED)
	public String getTrackPath(LabelIOBean labelIOBean) {
		List<Path> path = pathDao.queryAll();
		List<LabelReadingMachine> labelReadMachine = labelReadingMachineDao.queryAll();
		Map<String, LabelReadingMachine> mapReaders = GroupList.groupReaders(labelReadMachine);
		Map<String, Path> mapPath = GroupList.groupPath(path);
		String pathCoords = findTrackPoint(mapPath, labelIOBean.getAllList(), mapReaders);
		return pathCoords;
	}

	public String findTrackPoint(Map<String, Path> mapPath, List<SuperLabelIO> listIO,
			Map<String, LabelReadingMachine> mapReaders) {
		String returnCoords = "";
		String nextLrmID = "";
		boolean noExistPath = false;
		for (int i = 0; i < listIO.size(); i++) {
			String tempPath = "";
			SuperLabelIO labelIO = new SuperLabelIO();
			if ((i + 1) < listIO.size()) {
				labelIO = listIO.get(i + 1);
				nextLrmID = String.valueOf(labelIO.getLrmID());
			}
			labelIO = listIO.get(i);
			String lrmID = String.valueOf(labelIO.getLrmID());
			if (MapUtils.isNotEmpty(mapPath)) {
				String pathStr = "";
				for (Map.Entry<String, Path> path : mapPath.entrySet()) {
					String currentPathStr = path.getValue().getRemark() == null ? "" : path.getValue().getRemark();
					if (currentPathStr.indexOf("["+lrmID + "]:") >= 0 && currentPathStr.indexOf("["+nextLrmID + "]:") >= 0
							&& StringUtils.isNotEmpty(nextLrmID)) {
						if (StringUtils.isEmpty(pathStr)) {
							pathStr = currentPathStr;
						} else {
							if (pathStr.length() > currentPathStr.length()) {
								pathStr = currentPathStr;
							}
						}
					}
				}
				if (StringUtils.isNotEmpty(pathStr)) {
					tempPath = findIndex(pathStr, lrmID, nextLrmID, labelIO, listIO.size(), i);
					if (StringUtils.isNotEmpty(returnCoords) && !noExistPath) {
						String returnStr = returnCoords.substring(0, returnCoords.length() - 1);
						returnStr = returnStr.substring(0, returnStr.lastIndexOf(";") + 1);
						returnCoords = returnStr;
					}
					returnCoords += tempPath;
				}
			}
			if (StringUtils.isEmpty(tempPath)) {
				LabelReadingMachine labelMachine = mapReaders.get(lrmID);
				if (labelMachine != null) {
					returnCoords += lrmID + ":[" + labelMachine.getLrmX() + "," + labelMachine.getLrmY() + "],"
							+ labelIO.getInTime().toString("HH:mm:ss") + ";";
				}
				noExistPath = true;
			}
		}
		return returnCoords.toString();
	}

	public String findIndex(String pathStr, String lrmID, String nextLrmID, SuperLabelIO labelIO, int count, int current) {
		String pathLeft = "";
		String pathRight = "";
		String tempPath = "";
		if (pathStr.indexOf("["+lrmID + "]:") > pathStr.indexOf("["+nextLrmID + "]:")) {
			pathLeft = pathStr.substring(pathStr.indexOf("["+nextLrmID + "]:"), pathStr.indexOf("["+lrmID + "]:"));
			String intimeLeft = pathLeft.substring(0, pathLeft.indexOf(";")) + ","
					+ labelIO.getInTime().toString("HH:mm:ss") + ";";
			String lastPathLeft = pathLeft.substring(pathLeft.indexOf(";") + 1);
			pathLeft = intimeLeft + lastPathLeft;
			pathRight = pathStr.substring(pathStr.indexOf("["+lrmID + "]:"));
			pathRight = pathRight.substring(0, pathRight.indexOf(";")) + "," + labelIO.getInTime().toString("HH:mm:ss")
					+ ";";
			String[] pathCoords = pathLeft.substring(0, pathLeft.lastIndexOf(";")).split(";");
			String converLeft = "";
			for (int len = pathCoords.length - 1; len >= 0; len--) {
				converLeft += pathCoords[len] + ";";
			}
			pathLeft = converLeft;
			tempPath = pathRight + pathLeft;
		} else if (pathStr.indexOf("["+lrmID + "]:") < pathStr.indexOf("["+nextLrmID + "]:")) {
			pathLeft = pathStr.substring(pathStr.indexOf("["+lrmID + "]:"), pathStr.indexOf("["+nextLrmID + "]:"));
			String intimeLeft = pathLeft.substring(0, pathLeft.indexOf(";")) + ","
					+ labelIO.getInTime().toString("HH:mm:ss") + ";";
			String lastPathLeft = pathLeft.substring(pathLeft.indexOf(";") + 1);
			pathLeft = intimeLeft + lastPathLeft;
			pathRight = pathStr.substring(pathStr.indexOf("["+nextLrmID + "]:"));
			pathRight = pathRight.substring(0, pathRight.indexOf(";")) + "," + labelIO.getInTime().toString("HH:mm:ss")
					+ ";";
			tempPath = pathLeft + pathRight;
		} else if (pathStr.indexOf("["+lrmID + "]:") == pathStr.indexOf("["+nextLrmID + "]:")) {
			pathLeft = pathStr.substring(pathStr.indexOf("["+lrmID + "]:"));
			pathLeft = pathLeft.substring(0, pathLeft.indexOf(";")) + "," + labelIO.getInTime().toString("HH:mm:ss")
					+ ";";
			pathRight = pathStr.substring(pathStr.indexOf("["+nextLrmID + "]:"));
			pathRight = pathRight.substring(0, pathRight.indexOf(";")) + "," + labelIO.getInTime().toString("HH:mm:ss")
					+ ";";
			if ((current + 1) < count) {
				tempPath = pathLeft + pathRight;
			} else {
				tempPath = pathLeft;
			}
		}
		return tempPath;
	}

	public String findLastIndex(String pathStr, String lrmID, String nextLrmID, SuperLabelIO labelIO, int count,
			int current) {
		String pathLeft = "";
		String pathRight = "";
		String tempPath = "";
		if (pathStr.lastIndexOf(lrmID + ":") > pathStr.lastIndexOf(nextLrmID + ":")) {
			pathLeft = pathStr.substring(pathStr.lastIndexOf(nextLrmID + ":"), pathStr.lastIndexOf(lrmID + ":"));
			String intimeLeft = pathLeft.substring(0, pathLeft.indexOf(";")) + ","
					+ labelIO.getInTime().toString("HH:mm:ss") + ";";
			String lastPathLeft = pathLeft.substring(pathLeft.indexOf(";") + 1);
			pathLeft = intimeLeft + lastPathLeft;
			pathRight = pathStr.substring(pathStr.lastIndexOf(lrmID + ":"));
			pathRight = pathRight.substring(0, pathRight.indexOf(";")) + "," + labelIO.getInTime().toString("HH:mm:ss")
					+ ";";
			String[] pathCoords = pathLeft.substring(0, pathLeft.lastIndexOf(";")).split(";");
			String converLeft = "";
			for (int len = pathCoords.length - 1; len >= 0; len--) {
				converLeft += pathCoords[len] + ";";
			}
			pathLeft = converLeft;
			tempPath = pathRight + pathLeft;
		} else if (pathStr.lastIndexOf(lrmID + ":") < pathStr.lastIndexOf(nextLrmID + ":")) {
			pathLeft = pathStr.substring(pathStr.lastIndexOf(lrmID + ":"), pathStr.lastIndexOf(nextLrmID + ":"));
			String intimeLeft = pathLeft.substring(0, pathLeft.indexOf(";")) + ","
					+ labelIO.getInTime().toString("HH:mm:ss") + ";";
			String lastPathLeft = pathLeft.substring(pathLeft.indexOf(";") + 1);
			pathLeft = intimeLeft + lastPathLeft;
			pathRight = pathStr.substring(pathStr.lastIndexOf(nextLrmID + ":"));
			pathRight = pathRight.substring(0, pathRight.indexOf(";")) + "," + labelIO.getInTime().toString("HH:mm:ss")
					+ ";";
			tempPath = pathLeft + pathRight;
		} else if (pathStr.lastIndexOf(lrmID + ":") == pathStr.lastIndexOf(nextLrmID + ":")) {
			pathLeft = pathStr.substring(pathStr.lastIndexOf(lrmID + ":"));
			pathLeft = pathLeft.substring(0, pathLeft.indexOf(";")) + "," + labelIO.getInTime().toString("HH:mm:ss")
					+ ";";
			pathRight = pathStr.substring(pathStr.lastIndexOf(nextLrmID + ":"));
			pathRight = pathRight.substring(0, pathRight.indexOf(";")) + "," + labelIO.getInTime().toString("HH:mm:ss")
					+ ";";
			if ((current + 1) < count) {
				tempPath = pathLeft + pathRight;
			} else {
				tempPath = pathLeft;
			}
		}
		return tempPath;
	}
	
	/**
	 * 实时轨迹查询页面(查出符合条件的所有人员信息)
	 * @param bean
	 * @param oldBean
	 * @param user
	 * @return
	 */
	@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED)
	public RealTimeLabelIOBeanBean getRealTimeLabelIOAll(RealTimeLabelIOBeanBean bean, RealTimeLabelIOBeanBean oldBean, UserBean user){
		if (bean.equals(oldBean)){
			bean.setAllList(oldBean.getAllList());
			bean.setPageSize(10);
			bean.setList(bean.getAllList().subList(bean.getCurrentRow(), bean.getLastRow()));
		} else {
			StringBuffer sql = new StringBuffer("");
			sql.append("from ViewRealEmpData where 1=1 \n");
			if (StringUtils.isNotEmpty(bean.getEmpName().trim())){
				sql.append(" and empName like'%" + bean.getEmpName()+"%'");
			}
			if (StringUtils.isNotEmpty(bean.getLabelID().trim())){
				sql.append(" and empLabelID  like'%" + bean.getLabelID()+"%'");
			}
			if (StringUtils.isNotEmpty(bean.getDepID()) && !"0".equals(bean.getDepID())){
				sql.append(" and empDepID = " + bean.getDepID());
			} else if("0".equals(bean.getDepID())) {
				sql.append(" and empDepID in (" + user.getRole().getDepartment() + ")");
			}
			if (StringUtils.isNotEmpty(bean.getWorkTypeID()) && !"0".equals(bean.getWorkTypeID())){
				sql.append(" and empWorkTypeID = " + bean.getWorkTypeID());
			}
			if (StringUtils.isNotEmpty(bean.getInTime())){
				sql.append(" and startTime > '" + bean.getInTime() + "'");
			}
			if (StringUtils.isNotEmpty(bean.getOutTime())){
				sql.append(" and startTime < '" + bean.getOutTime() + "'");
			}
			bean.setAllList(viewRealEmpDataDao.queryHql(sql.toString()));
			bean.setList(bean.getAllList().subList(bean.getCurrentRow(), bean.getLastRow()));
		}
		return bean;
	}
}
